import mod_gui,mod_actor
from mod_vector import subtractVectors
import math,random
import mod_line

def fireProjectile(actor,projectile,target,oddsFunction,keepGoing=True,rotateImage=False):
    line = mod_line.getBulletLine(actor.location[0],actor.location[1],target)
    level,coords = actor.location
    dx = target[0] - coords[0]
    dy = target[1] - coords[1]
    path = []
    nextTarget = target
    index = 0
    for space in line:
        path.append(space)
        if space in level.entityMap:
            entity = level.entityMap[space]
            if entity.blocksBullets:
                break
            else:
                odds = oddsFunction(actor,space)
                if space == target:
                    odds = odds * 2
                #print odds
                if random.random() < odds:
                    break
        if keepGoing and space == nextTarget:
            nextTarget = (space[0]+dx,space[1]+dy)
            line += mod_line.generateLine(space, nextTarget)
    projectileEvent = mod_actor.ProjectileEvent(coords,line,path,projectile.glyph,rotateImage)
    mod_gui.theGUI.playProjectileAnimation(projectileEvent)
    finalDestination = path[-1]
    if finalDestination in level.entityMap:
        otherEntity = level.entityMap[finalDestination]
        mod_gui.theGUI.messages.append('IT HITS '+otherEntity.glyph+'.')
        
        if projectile.stopsBeforeWall and otherEntity.blocksBullets:
            # Prevent an item from getting stuck in a wall, door, etc:
            if len(path) > 1:
                finalDestination = path[-2]
            else:
                finalDestination = coords
        # Inflict impact damage.
        #otherActor.takeDamage(self.power)
        
    newLocation = (level,finalDestination)
    projectile.setLocation(newLocation)
    if projectile.impactEffect:
        projectile.impactEffect.doIt(projectile)

def doAreaOfEffectDamage(originLocation,radius,explosionGlyph,damageFunction,damageType):
    level,origin = originLocation
    affectedTiles = set()
    for x in range(origin[0]-radius,origin[0]+radius+1):
        for y in range(origin[1]-radius,origin[1]+radius+1):
            tile = (x,y)
            vector = subtractVectors(origin,tile)
            distance = math.hypot(vector[0],vector[1])
            if distance <= radius and (tile == origin or mod_line.inRange(level,origin,tile)):
                affectedTiles.add((tile,distance))
    
    aoeEvent = AreaOfEffectEvent(origin,affectedTiles,explosionGlyph)
    mod_gui.theGUI.playAOEAnimation(aoeEvent)
    
    for tile,distance in affectedTiles:
        entity = level.entityMap.get(tile)
        if entity:
            damage = damageFunction(distance)
            entity.takeDamage(damage,damageType)

class AreaOfEffectEvent:
    def __init__(self,origin,affectedTiles,explosionGlyph):
        self.affectedTiles = affectedTiles
        self.explosionGlyph = explosionGlyph
        self.origin = origin
        